import * as React from 'react';
import { Input } from 'antd';
import { InputProps } from 'antd/lib/Input/Input';

interface IInputNumberProps extends InputProps {
    value?: string;
    digit?: number//小数位数
    max?: number;
    min?: number;
    onChange?: (value: any) => void;
};

interface IInputNumberState {
    value?: string;
}

class InputNumber extends React.Component<IInputNumberProps, IInputNumberState> {
    constructor(props: IInputNumberProps) {
        super(props);
        this.state = {
            value: this.props.value || ''
        };
    }
    handleChange = (evt: React.FormEvent<any>) => {
        const target = evt.target as HTMLInputElement;
        const value = target.value;
        this.triggerChange(value, true);
    }
    handleBlur = (evt: React.FormEvent<any>) => {
        const target = evt.target as HTMLInputElement;
        const value = target.value;
        this.triggerChange(value, false);
    }
    triggerChange = (value: string, tempAble: boolean) => {
        const validValue = this.getValidValue(value, tempAble);
        const {onChange} = this.props;
        this.setState({ value: validValue }, () => {
            if (onChange) {
                if (this.isValidValue(validValue, null, false) == null) {
                    onChange(null);
                } else {
                    onChange(validValue);
                }
            }
        });
    }
    getValidValue(value: string, tempAble: boolean) {
        if (this.isInvalidValue(value)) {
            return null;
        }
        const {max, min, digit} = this.props;
        let prevValue = this.state.value;
        let reg;
        if (digit != undefined && digit >= 0) {
            reg = new RegExp(`^[0-9]+(\\.[0-9]{0,${digit}})?$`);
        } else {
            reg = new RegExp(`^[0-9]+$`);
        }

        if (!reg.test(value)) {
            if (reg.test(prevValue)) {
                return prevValue
            } else {
                return null;
            }
        }
        if (!tempAble) {
            prevValue = this.isValidValue(prevValue, null, tempAble);
        }
        return this.isValidValue(value, prevValue, tempAble);
    }

    isValidValue(value: string, defaultValue: string, tempAble: boolean): string {
        const {max, min, digit} = this.props;
        const flag = /^-?\d?\.[0]?$/.test(value);
        const endDot = new RegExp(`^-?\\d+\\.0{0,${digit}}$`).test(value);
        const endDigit = new RegExp(`^-?\\d+\\.\\d{${digit}}$`).test(value);
        const num = parseFloat(value);

        if (max !== undefined && num > max) {
            return defaultValue;
        }
        if (min !== undefined && num < min && (endDigit || !this.enableTempValue(value, tempAble))) {
            return defaultValue;
        }
        const retNum = num + '';
        const retDot = num + '.';
        if (endDot || endDigit) {
            return value;
        } else {
            return flag && tempAble ? retDot : retNum;
        }
    }

    enableTempValue(value: string, tempAble: boolean): boolean {
        if (!tempAble) {
            return false;
        }
        const min = parseInt(this.props.min + '');
        const a = parseInt(value);
        return min === a;
    }

    //无效的值 
    isInvalidValue(value: string | number): boolean {
        return value == null || value == undefined || value == 'null' || value == 'undefined' || value == 'NaN' || value == '';
    }

    getProps() {
        const props = Object.assign({}, this.props);
        delete props.digit;
        delete props.min;
        delete props.max;
        return props;
    }

    render() {
        const props = this.getProps();
        let value = this.state.value;
        this.isInvalidValue(value) ? '' : value;
        return (
            <Input {...props} onChange={this.handleChange} onBlur={this.handleBlur} value={value} />
        );
    }
}

export default InputNumber;
